package com.gaotu.demo.mybatis;

import com.gaotu.demo.User;
import com.gaotu.demo.UserDao;
import com.gaotu.demo.mybatis.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.function.Function;

@Component
public class MapperBasedUserDao implements UserDao {

    @Autowired
    private ResourceLoader resourceLoader;

    private SqlSessionFactory sqlSessionFactory;

    @PostConstruct
    public void init() throws Exception{
        Resource resource = resourceLoader.getResource("classpath:/mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(resource.getInputStream());
        this.sqlSessionFactory  = sqlSessionFactory;
    }

    <T> T doWithUserMapper(Function<UserMapper, T> function){
        try (SqlSession sqlSession = sqlSessionFactory.openSession(true)){
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            return function.apply(userMapper);
        }
    }

//    @Override
//    public void insert(User user) {
//        UserMapper userMapper = null;
//        try (SqlSession sqlSession =
//                sqlSessionFactory
//                 .openSession(true)) {
//            userMapper = sqlSession
//                    .getMapper(UserMapper.class);
//        }
//        userMapper.insert(user);
//    }

    @Override
    public void insert(User user) {
        doWithUserMapper(userMapper -> {
            userMapper.insert(user);
            return null;
        });
    }

    @Override
    public void update(User user) {
        doWithUserMapper(userMapper -> {
            userMapper.updateByPrimaryKey(user);
            return null;
        });
    }

    @Override
    public void deleteById(Long id) {
        doWithUserMapper(userMapper -> {
            userMapper.deleteByPrimaryKey(id);
            return true;
        });
    }

    @Override
    public User getById(Long id) {
        return doWithUserMapper(userMapper -> userMapper.selectByPrimaryKey(id));

    }

    @Override
    public User getByName(String name) {
        return doWithUserMapper(userMapper -> userMapper.selectByName(name));

    }


}
